package ar.com.sectorwine.controllers;

import java.security.Principal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import javax.validation.Validator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;

import ar.com.sectorwine.dto.StockDTO;
import ar.com.sectorwine.dto.StockDTOMapper;
import ar.com.sectorwine.entities.Empresa;
import ar.com.sectorwine.entities.Stock;
import ar.com.sectorwine.entities.Users;
import ar.com.sectorwine.repository.InteresStockRepository;
import ar.com.sectorwine.services.EmpresasService;
import ar.com.sectorwine.services.StockService;
import ar.com.sectorwine.services.UsuarioService;
import excepciones.ExcepcionGeneral;

/**
 * Handles requests for the application home page.
 */
@Controller
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class StockController {

	@Autowired
	private EmpresasService empresasService;
	@Autowired
	private StockService stockService;
	@Autowired
	private UsuarioService usuarioService;
	@Autowired
	private Validator validator;
	@Autowired
	private StockDTOMapper stockDTOMapper;
	@Autowired
	InteresStockRepository interesStockRepository;

	private static final Logger logger = LoggerFactory
			.getLogger(StockController.class);

	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "stock_alta", method = RequestMethod.GET)
	public String alta_stock(Locale locale, Model model, @RequestParam String id) {

		logger.info("Welcome home! the client locale is " + locale.toString());

		SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
		StockDTO stock = new StockDTO();
		stock.setFechaCreacionStock(sdf.format(new Date()));
		stock.setId(Long.parseLong(id));	

		model.addAttribute("variedades",
				(List<String>) stockService.getParametro("variedad"));
		model.addAttribute("stockDTO", stock);

		return "stocks/stocks_alta";
	}

	@RequestMapping(value = "stock_alta", method = RequestMethod.POST)
	public ModelAndView create_stock(
			@Valid @ModelAttribute("stockDTO") StockDTO stockDTO,
			BindingResult result, SessionStatus status, Principal principal) {
		try {
			logger.info("controller");

			Set<ConstraintViolation<StockDTO>> failures = validator
					.validate(stockDTO);
			ModelAndView mav;
			if (failures.size() == 0) {

				Stock stock = stockDTOMapper
						.obtenerObjetoDelDominioDesdeDTO(stockDTO);

				if (stock != null) {
					stockService.crearStock(stockDTO.getId(), stock);
					status.setComplete();
					// ModelAndView("stocks/stocks_detalle");
					mav = new ModelAndView("stocks/stocks_listar");
					Empresa empresa = empresasService.getEmpresa(stockDTO
							.getId() + "");
					List<Stock> listaStock = stockService
							.listarStockAlta(empresa.getId());
					if (!listaStock.isEmpty()) {

						List<StockDTO> DTOsStocks = stockDTOMapper
								.listarDTOsStockDesdeStocks(listaStock);
						mav.addObject("mis_stocks", DTOsStocks);
						mav.addObject("idEmpresa", empresa.getId());
						return mav;
					} else {
						mav = new ModelAndView("stocks/stocks_alta");
						SimpleDateFormat sdf = new SimpleDateFormat(
								"dd-MM-yyyy");
						StockDTO stock1 = new StockDTO();
						stock1.setFechaCreacionStock(sdf.format(new Date()));
						stock1.setId(stockDTO.getId());
						mav.addObject("variedades", (List<String>) stockService
								.getParametro("variedad"));
						mav.addObject("stockDTO", stock);
						mav.addObject("mensajeCabecera",
								"No se encontraron productos disponibles");
						return mav;
					}

					//
					//
					// Users usuarioActual = usuarioService.getUsuario(principal
					// .getName());
					//
					// if (usuarioActual.getPerfilUsuario().getEmpresas() !=
					// null) {
					// mav.addObject("empresaPropia",
					// usuarioActual.getPerfilUsuario().getEmpresas()
					// .contains(empresa));
					// } else {
					// mav.addObject("empresaPropia", false);
					// }
					//
					// mav.addObject("mensajeCabecera",
					// "El stock se dio de alta con exito!");
					// mav.addObject("stock", stock);
					// return mav;
				} else {
					mav = new ModelAndView("stocks/stocks_alta");
					mav.addObject("variedades", (List<String>) stockService
							.getParametro("variedad"));
					mav.addObject("stockDTO", stockDTO);
					return mav;
				}

			} else {

				mav = new ModelAndView("stocks/stocks_alta");
				mav.addObject("variedades",
						(List<String>) stockService.getParametro("variedad"));
				mav.addObject("stockDTO", stockDTO);
				for (Object o : failures) {
					logger.info(o.toString());
				}
				return mav;
			}

		} catch (ExcepcionGeneral e1) {

			ModelAndView mav = new ModelAndView("stocks/stocks_alta");
			mav.addObject("variedades",
					(List<String>) stockService.getParametro("variedad"));
			mav.addObject("stockDTO", stockDTO);

			if (e1.getAtributo() != null) {
				result.rejectValue(e1.getAtributo(), "messageCode",
						e1.getMessage());
			} else {
				mav.addObject("mensajeCabecera", e1.getMessage());
			}

			return mav;
		} catch (Exception e2) {

			ModelAndView mav = new ModelAndView("stocks/stocks_alta");
			mav.addObject("stockDTO", stockDTO);
			mav.addObject("variedades",
					(List<String>) stockService.getParametro("variedad"));
			mav.addObject("mensajeCabecera", "excepcion e2");
			return mav;
		}
	}

	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "stocks_listar", method = RequestMethod.GET)
	public ModelAndView lista(Locale locale, Model model, Principal principal,
			@RequestParam String id) {

		List<Stock> listaStock = stockService.listarStockAlta(Long
				.parseLong(id));

		// Si la empresa tiene al menos 1 producto cargado
		if (!listaStock.isEmpty()) {

			List<StockDTO> DTOsStocks = stockDTOMapper
					.listarDTOsStockDesdeStocks(listaStock);
			ModelAndView mav = new ModelAndView("stocks/stocks_listar");
			mav.addObject("mis_stocks", DTOsStocks);
			model.addAttribute("idEmpresa", id);
			return mav;
		} else {
			ModelAndView mav = new ModelAndView("stocks/stocks_alta");
			SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
			StockDTO stock = new StockDTO();
			stock.setFechaCreacionStock(sdf.format(new Date()));
			stock.setId(Long.parseLong(id));
			model.addAttribute("variedades",
					(List<String>) stockService.getParametro("variedad"));
			model.addAttribute("stockDTO", stock);
			mav.addObject("mensajeCabecera",
					"No se encontraron productos disponibles");
			return mav;
		}

	}

	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "stocks_detalle", method = RequestMethod.GET)
	public ModelAndView modificar(Locale locale, @RequestParam String id,
			Model model, Principal principal) {

		logger.info("Welcome home! the client locale is " + locale.toString());

		ModelAndView mav = new ModelAndView("stocks/stocks_detalle");

		Stock stock_buscado = stockService.getStock(id);
		Empresa empresa = stockService
				.obtenerEmpresaByStock(Long.parseLong(id));
		mav.addObject("stock", stock_buscado);
		mav.addObject("contacto", empresa);

		Users usuarioActual = usuarioService.getUsuario(principal.getName());

		if (usuarioActual.getPerfilUsuario().getEmpresas() != null) {
			mav.addObject("empresaPropia", usuarioActual.getPerfilUsuario()
					.getEmpresas().contains(empresa));
		} else {
			mav.addObject("empresaPropia", false);
		}
		// stockService.registrarInteres(id, principal.getName());
		return mav;
	}

	@RequestMapping(value = "/registrar_interes", method = RequestMethod.GET)
	public @ResponseBody
	String actualizar(@RequestParam Long id, Principal principal) {

		stockService.registrarInteres(id.toString(), principal.getName());

		return "success";
	}

	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "stocks_modificar", method = RequestMethod.GET)
	public String modificar_stock(Locale locale, Model model,
			@RequestParam String id) {

		logger.info("Welcome home! the client locale is " + locale.toString());

		Stock stock = stockService.getStock(id);

		model.addAttribute("variedades",
				(List<String>) stockService.getParametro("variedad"));
		model.addAttribute("stock",
				stockDTOMapper.obtenerDTODesdeObjetoDelDominio(stock));

		return "stocks/stocks_modificar";
	}

	@RequestMapping(value = "stocks_modificar", method = RequestMethod.POST)
	public ModelAndView modificar(
			@Valid @ModelAttribute("stock") StockDTO stockDTO,
			BindingResult result, SessionStatus status) {
		try {

			logger.info("controller");
			Stock stock = stockDTOMapper
					.obtenerObjetoDelDominioDesdeDTO(stockDTO);

			Set<ConstraintViolation<StockDTO>> failures = validator
					.validate(stockDTO);

			if (failures.size() == 0) {
				if (stock != null) {
					stockService.modificarStock(stock);
					status.setComplete();

					ModelAndView mav = new ModelAndView("redirect:home");
					// mav.addObject("stock", stockDTO);
					return mav;
				} else {
					ModelAndView mav = new ModelAndView(
							"stocks/stocks_modificar");
					mav.addObject("stock", stockDTO);
					return mav;
				}
			} else {
				ModelAndView mav = new ModelAndView("stocks/stocks_modificar");
				mav.addObject("stock", stockDTO);
				for (Object o : failures) {
					logger.info(o.toString());
				}
				return mav;
			}
		} catch (ExcepcionGeneral e1) {

			ModelAndView mav = new ModelAndView("stocks/stocks_alta");

			mav.addObject("stockDTO", stockDTO);

			if (e1.getAtributo() != null) {
				result.rejectValue(e1.getAtributo(), "messageCode",
						e1.getMessage());
			} else {
				mav.addObject("mensajeCabecera", e1.getMessage());
			}

			return mav;
		} catch (Exception e2) {

			ModelAndView mav = new ModelAndView("stocks/stocks_alta");
			mav.addObject("stockDTO", stockDTO);
			mav.addObject("");
			return mav;
		}

	}

	@RequestMapping(value = "stock_baja", method = RequestMethod.POST)
	public ModelAndView darBajaLogica(Locale locale, @RequestParam String id,
			Model model) {

		logger.info("controller");

		ModelAndView mav = new ModelAndView("redirect:home");
		mav.addObject("resultado", stockService.bajaStock(id));
		return mav;
	}

	@RequestMapping(value = "stock_vendido", method = RequestMethod.POST)
	public ModelAndView marcarVendido(Locale locale, @RequestParam String id,
			Model model) {

		logger.info("controller");
		stockService.marcarVendido(id);

		ModelAndView mav = new ModelAndView("stocks/stocks_detalle");

		Stock stock_buscado = stockService.getStock(id);
		mav.addObject("stock", stock_buscado);

		return mav;
	}

}